/**
 * @file lrc_parser.c
 * lrc解析相关函数
 */

/*********************
 *      INCLUDE
 *********************/
//导入库
#include <dirent.h>
#include <string.h>
#include <strings.h> // for strcasecmp
#include <windows.h>
#include <commdlg.h>
#include <time.h>
#include <tchar.h>
#include <unistd.h>
//导入自定义头文件
#include "lrc_parser.h"
#include "lv_demo_music.h"
#include "lv_demo_music_main.h"
#include "utf-8_to_gbk.h"


/**********************
 *   STATIC FUNCTIONS
 **********************/
// 解析时间标签 [mm:ss.xx]
static int parse_time_tag(const char* time_str, LyricTime* time) {
    int m, s, ms;

    // 尝试不同的时间格式
    if (sscanf(time_str, "%d:%d.%d", &m, &s, &ms) == 3) {
        time->minute = m;
        time->second = s;
        time->millisecond = ms * 10; // 百分秒转毫秒
    } else if (sscanf(time_str, "%d:%d", &m, &s) == 2) {
        time->minute = m;
        time->second = s;
        time->millisecond = 0;
    } else {
        return -1; // 解析失败
    }

    // 计算总毫秒数
    time->timestamp = time->minute * 60000 + time->second * 1000 + time->millisecond;
    return 0;
}

// 创建新的歌词行
static LyricLine* create_lyric_line(LyricTime time, const char* text) {
    LyricLine* line = (LyricLine*)malloc(sizeof(LyricLine));
    if (!line) return NULL;

    line->time = time;
    line->text = strdup(text);
    line->next = NULL;
    line->prev = NULL;

    return line;
}

// 释放歌词行
static void free_lyric_line(LyricLine* line) {
    if (line) {
        free(line->text);
        free(line);
    }
}

// 向链表插入歌词行（按时间排序）
static void insert_lyric_line(LrcFile* lrc, LyricLine* new_line) {
    if (!lrc->lines) {
        // 空链表
        lrc->lines = new_line;
        lrc->line_count++;
        return;
    }

    LyricLine* current = lrc->lines;
    LyricLine* prev = NULL;

    // 找到插入位置
    while (current && current->time.timestamp < new_line->time.timestamp) {
        prev = current;
        current = current->next;
    }

    if (!prev) {
        // 插入到链表头部
        new_line->next = lrc->lines;
        lrc->lines->prev = new_line;
        lrc->lines = new_line;
    } else {
        // 插入到中间或尾部
        prev->next = new_line;
        new_line->prev = prev;
        new_line->next = current;
        if (current) {
            current->prev = new_line;
        }
    }

    lrc->line_count++;
}

// 解析标签信息 [key:value]
static void parse_tag(LrcFile* lrc, const char* line) {
    char key[32], value[256];

    if (sscanf(line, "[%31[^:]:%255[^]]]", key, value) == 2) {
        // 去除value末尾的换行符和空格
        char* end = value + strlen(value) - 1;
        while (end >= value && (*end == '\n' || *end == '\r' || *end == ' ')) {
            *end = '\0';
            end--;
        }


        if (strcmp(key, "ti") == 0) {
            lrc->title = strdup(value);
        } else if (strcmp(key, "ar") == 0) {
            lrc->artist = strdup(value);
        } else if (strcmp(key, "al") == 0) {
            lrc->album = strdup(value);
        } else if (strcmp(key, "ge") == 0 || strcmp(key, "genre") == 0) {
            lrc->genre = strdup(value);
        } else if (strcmp(key, "length") == 0) {
            lrc->length = atoi(value);
        } else if (strcmp(key, "by") == 0) {
            lrc->by = strdup(value);
        } else if (strcmp(key, "offset") == 0) {
            lrc->offset = atoi(value);
        } else if (strcmp(key, "file") == 0 || strcmp(key, "filename") == 0) {
            lrc->filename = strdup(value);
        } else if (strcmp(key, "condition") == 0) {
            lrc->condition = strdup(value);
        }
    }
}

// 解析歌词行
static void parse_lyric_line(LrcFile* lrc, const char* line) {
    char buffer[512];
    strcpy(buffer, line);

    // 查找所有时间标签
    char* pos = buffer;
    while (*pos) {
        if (*pos == '[') {
            char* end = strchr(pos, ']');
            if (end) {
                // 提取时间标签部分
                char time_str[32];
                int len = end - pos - 1;
                if (len > 0 && len < sizeof(time_str)) {
                    strncpy(time_str, pos + 1, len);
                    time_str[len] = '\0';

                    // 检查是否是时间标签（包含数字和冒号）
                    int is_time_tag = 0;
                    for (int i = 0; time_str[i]; i++) {
                        if ((time_str[i] >= '0' && time_str[i] <= '9') || time_str[i] == ':' || time_str[i] == '.') {
                            is_time_tag = 1;
                            break;
                        }
                    }

                    if (is_time_tag) {
                        // 解析时间
                        LyricTime time;
                        if (parse_time_tag(time_str, &time) == 0) {
                            // 应用偏移量
                            time.timestamp += lrc->offset;

                            // 提取歌词文本（在最后一个时间标签之后）
                            char* lyric_text = end + 1;
                            // 跳过空格
                            while (*lyric_text == ' ') lyric_text++;

                            // 如果歌词文本不为空，创建歌词行
                            if (*lyric_text != '\0' && *lyric_text != '\n' && *lyric_text != '\r') {
                                LyricLine* new_line = create_lyric_line(time, lyric_text);
                                if (new_line) {
                                    insert_lyric_line(lrc, new_line);
                                }
                            }
                        }
                    }
                }
                pos = end + 1;
            } else {
                break;
            }
        } else {
            pos++;
        }
    }
}

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

// 主解析函数
LrcFile* lrc_parse_file(const char* filename) {
    FILE* file = fopen(filename, "r");

    if (!file) {
        char * filename_utf8 = gbk_to_utf8(filename);
        printf("错误：无法打开歌词文件 %s\n", filename_utf8);
        free(filename_utf8);
        return NULL;
    }

    // 初始化LRC结构
    LrcFile* lrc = (LrcFile*)malloc(sizeof(LrcFile));
    if (!lrc) {
        fclose(file);
        return NULL;
    }

    // 初始化成员
    lrc->title = NULL;
    lrc->artist = NULL;
    lrc->album = NULL;
    lrc->genre = NULL;
    lrc->length = NULL;
    lrc->by = NULL;
    lrc->offset = 0;

    lrc->filename = NULL;
    lrc->condition = NULL;

    lrc->lines = NULL;
    lrc->line_count = 0;

    char line[512];
    while (fgets(line, sizeof(line), file)) {

        // 去除换行符
        line[strcspn(line, "\r\n")] = '\0';

        // 跳过空行
        if (strlen(line) == 0) continue;

        // 检查是否是标签行
        if (line[0] == '[') {
            // 检查是否是时间标签 [mm:ss:xx]
            if (strchr(line, ':') && isdigit(line[1])) {
                // 检查是否是时间格式（包含数字和冒号）
                int is_time_line = 0;
                for (int i = 1; line[i] && line[i] != ']'; i++) {
                    if ((line[i] >= '0' && line[i] <= '9') || line[i] == ':' || line[i] == '.') {
                        is_time_line = 1;
                    } else if (line[i] == ':' && i > 1) {
                        // 已经确定是时间标签
                        break;
                    }
                }

                if (is_time_line) {
                    parse_lyric_line(lrc, line);
                } else {
                    // 是信息标签 [key:value]
                    parse_tag(lrc, line);
                }
            } else {
                // 是信息标签 [key:value]
                parse_tag(lrc, line);
            }
        }
    }

    fclose(file);

    // 在文件解析完成后，自动添加结束空标签
    if (lrc->lines && lrc->length > 0) {
        LyricLine* last_line = lrc->lines;
        while (last_line->next) last_line = last_line->next;

        // 检查最后一句歌词时间是否早于歌曲结束时间
        uint32_t last_line_time_seconds = last_line->time.timestamp / 1000;
        if (lrc->length > last_line_time_seconds) {
            LyricTime end_time;
            end_time.minute = lrc->length / 60;
            end_time.second = lrc->length % 60;
            end_time.millisecond = 0;
            end_time.timestamp = lrc->length * 1000;

            // 创建空歌词行
            LyricLine* empty_line = create_lyric_line(end_time, " ");
            if (empty_line) {
                insert_lyric_line(lrc, empty_line);
            }
        }
    }

    return lrc;
}

// 根据当前时间获取对应的歌词行
LyricLine* lrc_get_current_line(LrcFile* lrc, long current_time) {
    if (!lrc || !lrc->lines) return NULL;

    LyricLine* current = lrc->lines;
    LyricLine* result = NULL;

    while (current) {
        if (current->time.timestamp <= current_time) {
            result = current;
            current = current->next;
        } else {
            break;
        }
    }

    return result;
}

// 打印歌词文件信息
void lrc_print_info(LrcFile* lrc) {
    if (!lrc) {
        printf("歌词文件为空\n");
        return;
    }

    printf("=== 歌词文件信息 ===\n");
    printf("标题: %s\n", lrc->title ? lrc->title : "未知");
    printf("艺术家: %s\n", lrc->artist ? lrc->artist : "未知");
    printf("专辑: %s\n", lrc->album ? lrc->album : "未知");
    printf("流派: %s\n", lrc->genre ? lrc->genre : "未知");
    printf("时长: %d\n", lrc->length ? lrc->length : "未知");
    printf("编辑: %s\n", lrc->by ? lrc->by : "未知");
    printf("时间偏移: %d毫秒\n", lrc->offset);

    printf("文件名: %s\n", lrc->filename ? lrc->filename : "未知");
    printf("运动标签: %s\n", lrc->condition ? lrc->condition : "未知");

    printf("总行数: %d\n", lrc->line_count);
    printf("歌词内容:\n");

    LyricLine* line = lrc->lines;
    while (line) {
        printf("[%02d:%02d.%03d] %s\n",
               line->time.minute, line->time.second,
               line->time.millisecond, line->text);
        line = line->next;
    }
}

// 释放歌词文件资源
void lrc_free(LrcFile* lrc) {
    if (!lrc) return;

    free(lrc->title);
    free(lrc->artist);
    free(lrc->album);
    free(lrc->genre);
    free(lrc->by);

    free(lrc->filename);
    free(lrc->condition);

// 注意：length, offset是 int 类型，不是指针，不能 free!

    LyricLine* current = lrc->lines;
    while (current) {
        LyricLine* next = current->next;
        free_lyric_line(current);
        current = next;
    }
    free(lrc);
}

// 保存歌词到文件
int lrc_save_to_file(LrcFile* lrc, const char* filename) {
    FILE* file = fopen(filename, "w");
    if (!file) return -1;

    // 写入标签信息
    if (lrc->title) fprintf(file, "[ti:%s]\n", lrc->title);
    if (lrc->artist) fprintf(file, "[ar:%s]\n", lrc->artist);
    if (lrc->album) fprintf(file, "[al:%s]\n", lrc->album);
    if (lrc->genre) fprintf(file, "[ge:%s]\n", lrc->genre);
    if (lrc->length) fprintf(file, "[length:%d]\n", lrc->length);
    if (lrc->by) fprintf(file, "[by:%s]\n", lrc->by);
    fprintf(file, "[offset:%d]\n", lrc->offset);

    if (lrc->filename) fprintf(file, "[file:%s]\n", lrc->filename);
    if (lrc->condition) fprintf(file, "[condition:%s]\n", lrc->condition);

    fprintf(file, "\n");

    // 写入歌词行
    LyricLine* line = lrc->lines;
    while (line) {
        fprintf(file, "[%02d:%02d.%02d]%s\n",
                line->time.minute, line->time.second,
                line->time.millisecond / 10, line->text);
        line = line->next;
    }

    fclose(file);
    return 0;
}

/**
 * @brief 从指定文件夹读取所有LRC文件并初始化音乐数据
 * @param folder_path LRC文件所在文件夹路径
 * @return 成功读取的文件数量，失败返回-1
 */
int init_music_data_from_lrc(const char* folder_path) {
    DIR* dir;
    struct dirent* entry;
    int file_count = 0;

    // 安全检查
    if (!folder_path) {
        printf("错误: 文件夹路径为空\n");
        return -1;
    }

    // 打开目录
    dir = opendir(folder_path);
    if (!dir) {
        printf("错误: 无法打开文件夹 %s\n", folder_path);
        return -1;
    }

    // 先初始化所有指针为NULL，防止野指针
    for(int i = 0; i < MAX_TRACKS; i++) {
        title_list[i] = NULL;
        artist_list[i] = NULL;
        genre_list[i] = NULL;
        filename_list[i] = NULL;
        condition_list[i] = NULL;
        time_list[i] = 0;
    }

    // 遍历目录
    while ((entry = readdir(dir)) != NULL && file_count < MAX_TRACKS) {
        // 检查文件扩展名
        char* ext = strrchr(entry->d_name, '.');
        if (ext && strcasecmp(ext, ".lrc") == 0) {
            // 构建完整文件路径
            char file_path[512];
            snprintf(file_path, sizeof(file_path), "%s\\%s", folder_path, entry->d_name);

            printf("正在解析LRC文件: \n%s\n", gbk_to_utf8(file_path));

            // 解析LRC文件
            LrcFile* lrc = lrc_parse_file(file_path);
            if (lrc) {
                // 安全地分配内存
                if (lrc->title && strlen(lrc->title) > 0) {
                    title_list[file_count] = strdup(lrc->title);
                } else {
                    // 使用文件名作为标题
                    char* title = strdup(entry->d_name);
                    char* dot = strrchr(title, '.');
                    if (dot) *dot = '\0';
                    title_list[file_count] = title;
                }

                if (lrc->artist) {
                    artist_list[file_count] = strdup(lrc->artist);
                } else {
                    artist_list[file_count] = strdup("未知艺术家");
                }

                // 使用LRC文件中的流派信息，如果没有则使用默认值
                if (lrc->genre) {
                    genre_list[file_count] = strdup(lrc->genre);
                } else {
                    genre_list[file_count] = strdup("未知流派");
                }

                // 使用LRC文件中的文件名，如果没有则使用默认值
                if (lrc->filename) {
                    filename_list[file_count] = strdup(lrc->filename);
                } else {
                    filename_list[file_count] = strdup("null");
                }

                // 使用LRC文件中的运动状态，如果没有则使用默认值
                if (lrc->condition) {
                    condition_list[file_count] = strdup(lrc->condition);
                } else {
                    condition_list[file_count] = strdup("正常");
                }

                // 计算歌曲时长：优先使用length标签，否则使用最后一句歌词的时间
                uint32_t track_length = 0;
                if (lrc->length > 0) {
                    // 直接使用length标签的值
                    track_length = lrc->length;
                } else if (lrc->lines) {
                    // 基于最后一句歌词计算时长
                    LyricLine* last_line = lrc->lines;
                    while (last_line->next) {
                        last_line = last_line->next;
                    }
                    // 转换为秒（毫秒/1000）
                    track_length = (last_line->time.timestamp / 1000) + 10;
                } else {
                    //使用默认歌曲时长: %d秒
                    track_length = 180; // 默认3分钟
                }

                time_list[file_count] = track_length;

                printf("成功加载一首歌曲: \n歌曲名称：%s\n歌手：%s \n流派：%s\n时长：%d秒 \n文件路径：%s\n标签：[%s]\n",
                       title_list[file_count],
                       artist_list[file_count],
                       genre_list[file_count],
                       time_list[file_count],
                       filename_list[file_count],
                       condition_list[file_count]);

                file_count++;
                // 释放LRC文件资源
                lrc_free(lrc);
            }else {
                printf("无法解析LRC文件: %s\n", file_path);
            }
        }
    }

    closedir(dir);

    printf("总共加载了 %d 首歌曲\n", file_count);

    return file_count;
}
